package org.dxy.domain.handler.product;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.domain.port.CommandHandler;
import org.dxy.domain.port.repository.IProductRepository;
import org.dxy.domain.command.product.CreateProductCommand;
import org.dxy.domain.event.DomainEvent;
import org.dxy.domain.model.aggregate.Product;
import org.dxy.types.common.CommandResult;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 创建产品命令处理器
 * @author: dxy
 * @createTime: 2025/8/17
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class CreateProductCommandHandler implements CommandHandler<CreateProductCommand, Long> {

    private final IProductRepository productRepository;
    private final ApplicationEventPublisher eventPublisher;

    @Transactional
    @Override
    public CommandResult<Long> handle(CreateProductCommand command) {
        try {
            log.info("开始处理创建产品命令: productCode={}", command.productCode());

            // 1. 检查产品编码是否已存在
            if (productRepository.existsByProductCode(command.productCode())) {
                return CommandResult.fail(null,"产品编码已存在: " + command.productCode());
            }

            // 2. 生成产品ID（这里简化处理，实际应该使用ID生成器）
            Long productId = System.currentTimeMillis();

            // 3. 创建产品聚合根
            Product product = Product.create(productId, command);

            // 4. 保存聚合根
            productRepository.save(product);

            // 5. 获取并发布领域事件
            List<DomainEvent> events = product.getDomainEvents();
            for (DomainEvent event : events) {
                log.info("发布领域事件: {}", event.getClass().getSimpleName());
                eventPublisher.publishEvent(event);
            }
            
            // 6. 清除已发布的事件
            product.clearDomainEvents();

            log.info("创建产品命令处理完成: productId={}, productCode={}", productId, command.productCode());
            return CommandResult.success(productId, "产品创建成功");

        } catch (Exception e) {
            log.error("创建产品失败: productCode={}", command.productCode(), e);
            return CommandResult.fail(null,"创建产品失败: " + e.getMessage());
        }
    }
}